package com.otaku.admin.security;

import com.alibaba.fastjson.JSON;
import com.otaku.admin.dao.entity.SelfUserDetails;
import com.otaku.admin.dao.entity.Token;
import com.otaku.admin.service.RedisTemplateService;
import com.otaku.admin.service.SelfUserDetailsService;
import com.otaku.admin.service.TokenService;
import com.otaku.admin.util.*;
import com.otaku.common.util.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author: zzx
 * @date: 2018/10/16 9:59
 * @description: 登出成功
 */
@Component
public class AjaxLogoutSuccessHandler implements LogoutSuccessHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(AjaxLogoutSuccessHandler.class);
    @Autowired
    private SelfUserDetailsService userDetailsService;
    @Autowired
    private RedisTemplateService redisTemplateService;
    @Autowired
    private TokenService tokenService;

    @Override
    public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        /**
         * 1.删除 redisToken
         * 2.Token 表该用户数据无效
         */
        String authHeader = httpServletRequest.getHeader("Authorization");
        if (authHeader != null) {
            String authToken = null;
            if (authHeader.startsWith("Bearer ")){
                authToken = authHeader.substring("Bearer ".length());
            } else {
                authToken = authHeader;
            }
            if (!StringUtils.isEmpty(authToken)){
                try {
                    String username = JwtTokenUtil.parseTokenStr(authToken);
                    boolean b = redisTemplateService.delKey(StringTypeConstant.getRedisTokenTitles(username));
                    LOGGER.info("用户{} ===>登出 删除redis token:{}", username, b);
                    Token tokenDB = tokenService.findByAccessToken(authToken,NumericTypeConstant.TOKEN_STATUS_SUCCESS);
                    if (tokenDB != null) {
                        tokenService.updateStatusByUserId(tokenDB.getUserId(), NumericTypeConstant.TOKEN_STATUS_INVALID);
                    }
                } catch (Exception e) {
                    /**
                     * 可能存在的运行中token失效的情况,造成解析username失败
                     */
                    LOGGER.error("验证token异常：{}", e.getMessage());
                    Token tokenDB = tokenService.findByAccessToken(authToken,NumericTypeConstant.TOKEN_STATUS_SUCCESS);
                    if (tokenDB != null) {
                        SelfUserDetails userDetails = userDetailsService.findByUserId(tokenDB.getUserId());
                        String username = userDetails.getUsername();
                        boolean b = redisTemplateService.delKey(StringTypeConstant.getRedisTokenTitles(username));
                        LOGGER.info("用户{} ===>登出 删除redis token:{}", username, b);
                        tokenService.updateStatusByUserId(tokenDB.getUserId(), NumericTypeConstant.TOKEN_STATUS_INVALID);
                    }
                }
            }
        }
        httpServletResponse.setHeader("Content-type", "text/html;charset=UTF-8");
        httpServletResponse.getWriter().write(JSON.toJSONString(ResultVO.result(ResultEnum.USER_LOGOUT_SUCCESS, true)));
    }

}
